import './boot';
import 'reflect-metadata';
import * as bodyParser from 'body-parser';
import * as http from 'http';
import * as express from 'express';
import swagger from 'swagger-express-middleware';
import { Container, injectable } from 'inversify';
import { InversifyExpressServer } from 'inversify-express-utils';
import rootControllerFactory from './controllers/root';
import userControllerFactory from './controllers/agent';
import { bindSocketIO } from './socket';
import { makeLabelLogger, llog, lerror } from './util/logger';
import DefaultConfig from './config';
import { initRedis, redisClient } from './util/redis';
import { EventEmitter } from 'events';
// import * as pi from '../../shared/src/protocolInterface';
// console.log(pi);

export let app: express.Application;
export let Config = DefaultConfig;
export let appEvent = new EventEmitter();

export let startApp = async function() {
	// 加载配置
	Config = DefaultConfig;
	try {
		let customConfigPath = './config.dev';
		let CustomConfig = await import(customConfigPath);
		Config = CustomConfig.default;
		//
	} catch (e) {
		llog('no custom config');
	}

	process.on('uncaughtException', error => {
		console.log('uncaught exception', error);
	});

	/*
	// 连接redis
	if (!(await initRedis(Config))) {
		llog('no redis found');
		process.exit(1);
	}
	*/

	// 创建一个router用来加载swagger
	const router = express.Router({
		caseSensitive: false,
		mergeParams: false,
		strict: false,
	});

	// 加载swagger，得到中间件们
	let middleware = await new Promise<swagger.SwaggerMiddleware>((fill, reject) => {
		swagger('swagger/swagger.yaml', router, function(err, middleware) {
			if (err) reject(err);
			else fill(middleware);
		});
	});

	// 挂一个swagger ui
	router.use(middleware.files({}));
	router.use('/api-docs/swagger', express.static('swagger'));
	router.use('/api-docs/swagger/assets', express.static('node_modules/swagger-ui-dist'));

	// 创建ioc容器和服务器
	const container = new Container();
	const ieServer = new InversifyExpressServer(container, router);
	ieServer
		.setConfig((app: express.Application) => {
			app.use(bodyParser.json());
			// 挂上swagger中间件
			app.use(middleware.metadata());
			app.use(middleware.parseRequest());
			// app.use(middleware.validateRequest());
		})
		.setErrorConfig((app: express.Application) => {
			app.use((err: any, request: express.Request, response: express.Response, next: express.NextFunction) => {
				lerror(err.stack);
				response.status(err.status || 500).send(err.message);
			});
		});

	let apply = function(container: Container) {
		return [];
	};

	// 所有controller在这里初始化
	rootControllerFactory(container, apply);
	userControllerFactory(container, apply);

	// swagger的mock中间件，必须挂在最后，只有未实现的请求，才由它处理
	// app.use(middleware.mock());

	app = ieServer.build();
	appEvent.emit('inited');
};
